// 引入创建仓库的方法defineStore
import { defineStore } from 'pinia';
// 引入获取token和移除token和存储token的方法
import { getToken, removeToken, setToken } from '../utils/token-utils';
// 引入用户信息对象的类型,实际上是一个接口
import type { UserInfoState } from './interface';
// 引入api接口函数
import { loginApi, logoutApi, getUserInfoApi } from '@/api/acl/login'
// 引入用户信息数据的类型(自已定义的接口)
import type { UserInfoResponseModel } from '@/api/acl/model/loginModel'
// 引入静态路由数组、异步路由数组和任意路由
import { staticRoutes,allAsyncRoutes,anyRoute } from '@/router/routes';
// 引入路由器对象
import router from '@/router'
// 引入路由数组的数据类型
import type { RouteRecordRaw } from 'vue-router'
// 引入深拷贝的方法
import {cloneDeep} from 'lodash'

// 用来进行路由过滤的方法
function filterRoutes(asyncRoutes:RouteRecordRaw[],routeNames:string[]) { 
  return asyncRoutes.filter(route => { 
    // 判断路由名字数组中是否有路由对象的名字,如果没有就不用过滤
    if (routeNames.indexOf(route.name as string) === -1) return false
    // 判断:当前的路由对象中有没有子路由
    if (route.children && route.children.length > 0) {
      route.children = filterRoutes(route.children,routeNames)
     }
    return true
  })
}
// 动态的注册路由
function addRoutes(routes:RouteRecordRaw[]){
  routes.forEach(route =>{
    // 遍历每个路由对象，并把路由对象注册到路由器中
    router.addRoute(route)
  })
  // console.log(router.getRoutes());
  
}

// 重置路由
function resetRouter() { 
  // 先获取路由器中所有的路由
  const routes = router.getRoutes()
  // 遍历每个路由对象,从路由器对象中移除
  routes.forEach(route => { 
    if (route.name) { 
      // 从路由器对象中移除(根据路由器对象的名字)
      router.removeRoute(route.name as string)
    }
  })
  // 再把静态路由数组中的每个路由重新添加到路由器中
  staticRoutes.forEach(r=>router.addRoute(r))
}

// 用户信息
export const useUserInfoStore = defineStore('userInfo', {
  // 状态数据
  state: (): UserInfoState => ({
    token: getToken() as string, // 先从本地存储中获取token信息
    name: '', // 用户名字
    avatar: '', // 头像信息

    // 和权限相关的数据
    menuRoutes: [], // 路由数组
    roles: [], // 角色名字数组
    authBtnList:[] // 按钮权限的标识数组
  }),

  actions: {
    // 传入帐号和密码
    async login(username: string, password: string) {
      // 调用api接口函数,发送请求,传入参数,存储响应后的数据
      const { token } = await loginApi(username, password)
      // 缓存token和把token存储到pinia中
      setToken(token)
      this.token = token
    },
    // 获取用户信息
    async getInfo() {
      const userInfo: UserInfoResponseModel = await getUserInfoApi()
      // 存储用户名和头像和静态路由数组(按钮数组/角色数组/路由名字数组--心情好的时候再存储)
      this.name = userInfo.name
      this.avatar = userInfo.avatar

      // 先存储角色名字数组的数据
      this.roles = userInfo.roles
      // 然后存储按钮权限标识数组
      this.authBtnList = userInfo.buttons
      // 干掉了,过滤完所有的路由数组数据后,再进行存储(静态路由和异步路由和任意路由)
      // this.menuRoutes = staticRoutes
      this.setRoutes(userInfo.routes)
    },
    // 过滤路由及存储路由的方法
    setRoutes(routeNames:string[]) { 
      // 过滤路由
      const asyncRoutes = filterRoutes(cloneDeep(allAsyncRoutes), routeNames)
      // 添加路由(把过滤后的路由对象数组,重新的放在router路由器中进行路由的注册)
      addRoutes([...asyncRoutes,anyRoute])
      // 存储路由(把静态路由,过滤后的异步路由和任意路由放在menuRoutes中,为了页面中展示)
      this.menuRoutes=[...staticRoutes,...asyncRoutes]
    },
    // 退出
    async reset() {
      // 如果用户信息存在的情况下,退出才是合理的
      if (this.name) {
        await logoutApi()
      }
      // 删除local中保存的token
      removeToken()
      // 提交重置用户信息的mutation
      this.token = ''
      this.name = ''
      this.avatar = ''
      // 重置路由
      // 干掉按钮标识数据和路由数据和角色数据
      resetRouter()
      this.menuRoutes = []
      this.roles = []
      this.authBtnList=[]
    },
  },
});



